import {Body, Controller, Get, HttpStatus, Post, Query, Res} from '@nestjs/common';
import {Response} from 'express';
import {CommonResponseDto} from '../../dto/common.response.dto';
import {ApplyStatus, ResCode} from '../../common/constants';
import {ApplyService} from "../../service/apply.service";
import {ApproveService} from "../../service/approve.service";
import {ApplyUserService} from "../../service/apply.user.service";
import {ApplyDto} from "../../dto/apply.dto";
import {formatTime, uuid} from "../../common/utils";
import {CommonRedisService} from "../../service/common.redis.service";
import {CommonRequestService} from "../../service/common.request.service";
import {PaginationDataDto} from "../../dto/pagination.data.dto";
import {sendApproveMsg} from '../../common/common'


@Controller('apply-admin/apply')
export class ApplyController{
    constructor(private readonly applyService: ApplyService, private readonly approveService: ApproveService, private readonly applyUserService: ApplyUserService, private readonly commonRedisService: CommonRedisService, private readonly commonRequestService: CommonRequestService) {

    }

    @Post('/add')
    async addApply(@Body() applyDto: ApplyDto, @Res({ passthrough: true }) res: Response) {
        res.status(HttpStatus.OK);
        if (!applyDto.deviceSn || !applyDto.applyAccountId || !applyDto.applyUseDate || !applyDto.applyUseTimeRange) {
            return new CommonResponseDto(ResCode.ERROR, 'deviceSn applyAccountId applyUseDate applyUseTimeRange 必填', null)
        }
        if (applyDto.approveAccountIdList) {
            applyDto.status = ApplyStatus.PENDING
            applyDto.nextApproveAccountId = applyDto.approveAccountIdList.split(',')[0]
        } else {
            applyDto.status = ApplyStatus.PASSED
        }
        try {
            applyDto.id = uuid(32)
            applyDto.applyTime = new Date().getTime() + ''
            const result = await this.applyService.createOne(applyDto)
            try {
                // 如果有需要下一个审批人，给下一个审批人发送工作通知：审批消息
                if (applyDto.nextApproveAccountId) {
                    this.applyService.getOneById(applyDto.id).then((apply) => {
                        // @ts-ignore
                        sendApproveMsg(applyDto.nextApproveAccountId, [`${apply.applyUserInfo.name}申请使用[${apply.deviceInfo.deviceName}]${apply.deviceInfo.deviceType === 'dock' ? '机场' : '飞行器'}`,`使用时间：${apply.applyUseDate} ${apply.applyUseTimeRange}`,`申请人：${apply.applyUserInfo.name}`,`申请时间：${formatTime(Number(apply.applyTime))}`], {type: 'approve', status: ApplyStatus.PENDING}, {commonRedisService: this.commonRedisService, commonRequestService: this.commonRequestService})
                    })
                }
            } catch(e){

            }
            return new CommonResponseDto(ResCode.OK, '成功', result)
        } catch(e){
            console.log(e)
            return new CommonResponseDto(ResCode.ERROR, '服务异常', null)
        }
    }

    @Post('/cancel')
    async cancelApply(@Body() body: {id: string}, @Res({ passthrough: true }) res: Response) {
        res.status(HttpStatus.OK);
        if (!body.id) {
            return new CommonResponseDto(ResCode.ERROR, 'id 必填', null)
        }
        try {
            const result = await this.applyService.editOneStatus(body.id, ApplyStatus.CANCELED)
            return new CommonResponseDto(ResCode.OK, '成功', result)
        } catch(e){
            console.log(e)
            return new CommonResponseDto(ResCode.ERROR, '服务异常', null)
        }
    }

    @Get('/detail')
    async getApplyDetail(@Query() query: {id: string}, @Res({ passthrough: true }) res: Response) {
        res.status(HttpStatus.OK);
        if (!query.id) {
            return new CommonResponseDto(ResCode.ERROR, 'id 必填', null)
        }
        try {
            let user
            const apply = await this.applyService.getOneById(query.id)
            const approveList = await this.approveService.getAllByApplyId(query.id)
            if (apply.nextApproveAccountId) {
                user = await this.applyUserService.getOneByAccountId(apply.nextApproveAccountId)
            }
            return new CommonResponseDto(ResCode.OK, '成功', {
                detail: apply,
                approveList,
                nextApproveUser: user
            })
        } catch(e){
            console.log(e)
            return new CommonResponseDto(ResCode.ERROR, '服务异常', null)
        }
    }

    @Post('/pd-approve-list')
    async getPersonPendingApproveList(@Body() body: {nextApproveAccountId: string}, @Res({ passthrough: true }) res: Response) {
        res.status(HttpStatus.OK);
        if (!body.nextApproveAccountId) {
            return new CommonResponseDto(ResCode.ERROR, 'nextApproveAccountId 必填', null)
        }
        try {
            const data = await this.applyService.getAllPendingDataByApproveAccountId(body.nextApproveAccountId)
            return new CommonResponseDto(ResCode.OK, 'success', data)
        } catch(e){
            console.log(e)
            return new CommonResponseDto(ResCode.ERROR, '服务异常', null)
        }
    }

    @Post('/list')
    async getApplyList(@Body() body: {pageIndex: number, pageSize: number, applyAccountId: string | undefined, status: ApplyStatus | undefined}, @Res({ passthrough: true }) res: Response) {
        res.status(HttpStatus.OK);
        if (!body.pageIndex || body.pageIndex < 1) {
            body.pageSize = 1
        }
        if (!body.pageSize || body.pageSize < 1) {
            body.pageSize = 10
        }
        try {
            const data = await this.applyService.getPaginationDataByApplyAccountIdAndStatus(body.pageIndex, body.pageSize, body.applyAccountId, body.status)
            if (data && data.length === 2) {
                const pageTotal = Math.ceil(data[1]/body.pageSize);
                return new CommonResponseDto(ResCode.OK, 'success', new PaginationDataDto(
                    body.pageIndex, body.pageSize, pageTotal, data[1], data[0]
                ))
            }
            return new CommonResponseDto(ResCode.ERROR, '查询失败', null)
        } catch(e){
            console.log(e)
            return new CommonResponseDto(ResCode.ERROR, '服务异常', null)
        }
    }

    @Post('/my-list')
    async getMyApplyList(@Body() body: {pageIndex: number, pageSize: number, applyAccountId: string, status: ApplyStatus | undefined}, @Res({ passthrough: true }) res: Response) {
        res.status(HttpStatus.OK);
        if (!body.pageIndex || body.pageIndex < 1) {
            body.pageSize = 1
        }
        if (!body.pageSize || body.pageSize < 1) {
            body.pageSize = 10
        }
        if (!body.applyAccountId) {
            return new CommonResponseDto(ResCode.OK, 'success', new PaginationDataDto(
                body.pageIndex, body.pageSize, 0, 0, []
            ))
        }
        try {
            const data = await this.applyService.getPaginationDataByApplyAccountIdAndStatus(body.pageIndex, body.pageSize, body.applyAccountId, body.status)
            if (data && data.length === 2) {
                const pageTotal = Math.ceil(data[1]/body.pageSize);
                return new CommonResponseDto(ResCode.OK, 'success', new PaginationDataDto(
                    body.pageIndex, body.pageSize, pageTotal, data[1], data[0]
                ))
            }
            return new CommonResponseDto(ResCode.ERROR, '查询失败', null)
        } catch(e){
            console.log(e)
            return new CommonResponseDto(ResCode.ERROR, '服务异常', null)
        }
    }

    @Get('/device-plan')
    async getDevicePlanList(@Query() query: {deviceSn: string}, @Res({ passthrough: true }) res: Response) {
        res.status(HttpStatus.OK);
        if (!query.deviceSn) {
            return new CommonResponseDto(ResCode.ERROR, 'deviceSn 必填', null)
        }
        try {
            const planObj = {}
            const applyList = await this.applyService.getApplyDateTimeRangeByDevice(query.deviceSn)
            applyList.forEach((apply: ApplyDto) => {
                if (!planObj[apply.applyUseDate]) {
                    planObj[apply.applyUseDate] = []
                }
                planObj[apply.applyUseDate].push(apply.applyUseTimeRange)
            })
            return new CommonResponseDto(ResCode.OK, 'success', planObj)
        } catch(e){
            console.log(e)
            return new CommonResponseDto(ResCode.ERROR, '服务异常', null)
        }
    }
}
